/////////////////////////
// File: camera_settings.cpp
// Authors: Brian Fehrman and Scott Logan and Matt Richard
// Date: 3-27-2013
// 
// Purpose: Implementation file for the camera_settings functions
//       which are used to set various camera properties
//       for UVC compliant cameras using linux system
//       calls and uvcdynctrl. MUST HAVE uvcdynctrl
//       INSTALLED!
//////////////////////////

////////// Includes ///////////
#include "camera_settings.h"


/////////////////////////
// function: init_cams
// Authors: Brian Fehrman and Scott Logan and Matt Richard
// 
// Purpose: Change the settings for each camera. Right now
//          it makes the settings the same for all cameras.
//          Future update could include setting each
//          camera individually.
//////////////////////////
int init_cams( FileNode fs )
{
   int exp_abs;
   int exp_auto;
   int exp_auto_pri;
   int white_bal_temp_auto;
   vector< int > vid_list;
   
   fs["exposure_absolute"] >> exp_abs;
   fs["exposure_auto"] >> exp_auto;
   fs["exposure_auto_priority"] >> exp_auto_pri;
   fs["white_bal_temp_auto"] >> white_bal_temp_auto;
   fs["vid_list"] >> vid_list;
   
   //Change settings for each camera. Be careful on the order
   //in which the different auto exposure settings are called
   for( unsigned int vid = 0; vid < vid_list.size(); vid++ )
   {
      set_exposure_auto_priority( vid_list[ vid ], exp_auto_pri );
      set_exposure_auto( vid_list[ vid ], exp_auto );
      set_exposure_absolute( vid_list[ vid ], exp_abs );
      set_white_balance_temperatue_auto( vid_list[ vid ], white_bal_temp_auto );
   }
   
   return 0;
}

/////////////////////////
// function: set_exposure_absolute
// Authors: Brian Fehrman and Scott Logan and Matt Richard
// 
// Purpose: Sets the absolute exposure level of the camera.
//       Make sure that you set "Exposure, Auto" to 1
//       (manual mode) and "Exposure, Auto Priority" to 0
//       (auto exposure off) before calling this function.
//
//
//       Input Range: [ 1, 10000 ]    ///Less is more, counter-intuitively
//////////////////////////
bool set_exposure_absolute( int vid_num, int new_setting )
{
   static const string EXP_ABS_CALL = " -s \"Exposure (Absolute)\" ";
   string sys_call;
   stringstream vid, set;
   
   vid << vid_num;
   set << new_setting; 
   
   sys_call = BASE_CALL + vid.str() + EXP_ABS_CALL + set.str();
   
   if ( system( sys_call.c_str( ) ) )
      return false;
   
   return true;
}

/////////////////////////
// function: set_exposure_auto
// Authors: Brian Fehrman and Scott Logan and Matt Richard
// 
// Purpose: Sets exposure mode to manual or auto. Need to
//       call this function once and set to manual before calling
//       set_exposure_absolute.
//
//       1 - Manual Mode
//       3 - Auto Exposure Mode
//////////////////////////
bool set_exposure_auto( int vid_num, int new_setting )
{
   static const string AUTO_EXP_CALL = " -s \"Exposure, Auto\" ";
   string sys_call;
   stringstream vid, set;
   
   vid << vid_num;
   set << new_setting; 
   
   sys_call = BASE_CALL + vid.str() + AUTO_EXP_CALL + set.str();
   
   if ( system( sys_call.c_str( ) ) )
      return false;
   
   return true;
}

/////////////////////////
// function: set_exposure_auto_priority
// Authors: Brian Fehrman and Scott Logan and Matt Richard
// 
// Purpose: Turns on or off auto exposure.
//
//       0 - off
//       1 - on
//////////////////////////
bool set_exposure_auto_priority( int vid_num, int new_setting )
{
   static const string AUTO_EXP_CALL = " -s \"Exposure, Auto Priority\" ";
   string sys_call;
   stringstream vid, set;
   
   vid << vid_num;
   set << new_setting; 
   
   sys_call = BASE_CALL + vid.str() + AUTO_EXP_CALL + set.str();
   
   if ( system( sys_call.c_str( ) ) )
      return false;
   
   return true;
}

/////////////////////////
// function: set_white_balance_temperatue_auto
// Authors: Brian Fehrman and Scott Logan and Matt Richard
// 
// Purpose: Turns on or off auto white temperate balance.
//
//       0 - off
//       1 - on
//////////////////////////
bool set_white_balance_temperatue_auto( int vid_num, int new_setting )
{
   static const string WHITE_BAL_CALL = " -s \"White Balance Temperature, Auto\" ";
   string sys_call;
   stringstream vid, set;
   
   vid << vid_num;
   set << new_setting; 
   
   sys_call = BASE_CALL + vid.str() + WHITE_BAL_CALL + set.str();
   
   if ( system( sys_call.c_str( ) ) )
      return false;
   
   return true;
}
